home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / programming / c / supralib / developer / source.org / recdirinit.c < prev    next >
C/C++ Source or Header  |  1999-06-14  |  5KB  |  125 lines

  1. /****** RecDirInit ******************************************
  2. *
  3. *   NAME
  4. *       RecDirInit -- Initializes recursive files scanning process (V10)
  5. *       (dos V36)
  6. *
  7. *   SYNOPSIS
  8. *       error = RecDirInit(RecDirInfo)
  9. *
  10. *       UBYTE = RecDirInit(struct RecDirInfo *)
  11. *
  12. *   FUNCTION
  13. *       This function is required to start scanning files through entire
  14. *       or partial directory tree. It locks a directory path provided in
  15. *       RecDirInfo structure, then files can be examined by calling
  16. *       RecDirNext() function. Please see RecDirNext() for more
  17. *       explanation on how this is useful.
  18. *       You should initialize RecDirInfo by yourself, and you MUST set
  19. *       rdi_Path, rdi_Num, and rdi_Pattern.
  20. *
  21. *   INPUTS
  22. *       RecDirInfo - pointer to RecDirInfo structure, which should be
  23. *       allocated and initialized before RecDirInit() is called.
  24. *       You must set its rdi_Path field to starting directory path
  25. *       you want to scan.
  26. *       
  27. *       Set rdi_Num for maximum number of directories you wish to scan
  28. *       into. If you set rdi_Num to 1 it will only scan one level (that
  29. *       rdi_Path points to). If you set rdi_Num to -1 it will scan
  30. *       unlimited number of subdirectories deep.
  31. *
  32. *       If rdi_Pattern field is non-NULL and points to a string then
  33. *       calling RecDirNext will only return files that match the
  34. *       pattern string. NOTE that rdi_Pattern should point to a string
  35. *       which has been parsed with ParsePattern().
  36. *
  37. *   RESULT
  38. *       error - 0 if no error, otherwise returns one of the following
  39. *       errors (also see libraries/supra.h):
  40. *           RDI_ERR_FILE - Path provided in rdi_Path points to a file
  41. *                          not directory.
  42. *           RDI_ERR_NONEXIST - Path provided in rdi_Path does not exist.
  43. *           RDI_ERR_MEM - not enough memory to execute RecDirInit().
  44. *
  45. *   EXAMPLE
  46. *       Please see an example in RecDirNext() function.
  47. *
  48. *   NOTES
  49. *       IMPORTANT: You MUST open dos.library before calling RecDirInit()!
  50. *       rdi_Path is a path relative to a current path your program uses.
  51. *       That means you can set rdi_Path to "" to scan from current
  52. *       directory, or "/" to scan parent directory.
  53. *
  54. *   BUGS
  55. *       None found yet.
  56. *
  57. *   SEE ALSO
  58. *       RecDirFree(), RecDirNext(), libraries/supra.h
  59. *
  60. **************************************************************************/
  61.  
  62. #include <proto/exec.h>
  63. #include <proto/dos.h>
  64. #include <exec/memory.h>
  65. #include <string.h>
  66. #include <libraries/supra.h>
  67.  
  68. UBYTE RecDirInit(struct RecDirInfo *rdi)
  69. {
  70.     BPTR lock;
  71.     struct FileInfoBlock *fib;
  72.     struct LockNode *ln;
  73.     char *lnPath;
  74.     int len;
  75.  
  76.     if ((lock = Lock(rdi->rdi_Path, ACCESS_READ)) == NULL) return(RDI_ERR_NONEXIST);
  77.  
  78.     if (fib = AllocMem(sizeof(struct FileInfoBlock), 0L)) {
  79.         if (Examine(lock, fib)) {
  80.             if (fib->fib_DirEntryType > 0) { /* Directory */
  81.                     if (ln = AllocMem(sizeof(struct LockNode), 0L)) {
  82.  
  83.                         /* Everything all right till now */
  84.                         /* Now first prepare to copy a path */
  85.  
  86.                         if (lnPath = AllocMem(strlen(rdi->rdi_Path)+2, 0L)) {
  87.                             strcpy(lnPath, rdi->rdi_Path);
  88.  
  89.                             /* Alter path's ending: check for slash etc. */
  90.                             len = strlen(lnPath);
  91.                             if (len > 0) {
  92.                                 if (lnPath[len-1] != '/' && lnPath[len-1] != ':') {
  93.                                     strcat(lnPath,"/");
  94.                                 }
  95.                             }
  96.  
  97.                             ln->ln_Succ = NULL;
  98.                             ln->ln_Pred = NULL;
  99.                             ln->ln_FIB  = fib;
  100.                             ln->ln_Lock = lock;
  101.                             ln->ln_Path = lnPath;
  102.                             ln->ln_Len  = strlen(rdi->rdi_Path)+2;
  103.  
  104.                             rdi->rdi_Node = ln;
  105.                             rdi->rdi_Deep = 1;
  106.                             return(0);
  107.                         }
  108.                     }
  109.             } else if (fib->fib_DirEntryType < 0) {   /* Path is file */
  110.                 FreeMem(fib, sizeof(struct FileInfoBlock));
  111.                 UnLock(lock);
  112.                 return(RDI_ERR_FILE); /* Indicate that path is a file not dir */
  113.             }
  114.         }
  115.     }
  116.  
  117.     if (ln) FreeMem(ln,sizeof(struct LockNode));
  118.     if (fib) FreeMem(fib, sizeof(struct FileInfoBlock));
  119.     if (lock) UnLock(lock);
  120.  
  121.     return(RDI_ERR_MEM);   /* No success */
  122. }
  123.  
  124.  
  125.